﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

using ApproveFlowEngine.Enums.Core;

using Volo.Abp;
using Volo.Abp.Domain.Entities;

namespace ApproveFlowEngine.Core.Base
{
    public class WorkNode : Entity<Guid>
    {
        #region Internal Constructors

        public WorkNode(Guid id)
        {
            Id = id;
            NodeType = NodeType.Simple;
            IsLeaf = true;
        }

        #endregion Internal Constructors



        #region Private Constructors

        protected WorkNode()
        {
            NodeType = NodeType.Simple;
            IsLeaf = true;
        }

        #endregion Private Constructors



        #region Public Properties
        public bool Activity { get; protected set; } = false;
        public Guid? ApproverId { get; set; }

        [NotMapped]
        public WorkNode? Before { get; set; }

        [NotMapped]
        public virtual List<WorkNode> Children { get; set; } = new List<WorkNode>();

        public List<Guid> Flies { get; set; } = new List<Guid>();
        public WorkFlow? Flow { get; set; } = null!;
        public Guid? FlowId { get; set; }
        public int Index { get; set; }
        public bool IsLeaf { get; init; }

        [NotMapped]
        public WorkNode? Next { get; set; }

        public virtual NodeType NodeType { get; init; }
        public WorkNodeComplex? Parent { get; set; }
        public Guid? ParentId { get; set; }
        public string? Remark { get; set; }
        public virtual ApproveNodeStatus Status { get; protected set; } = ApproveNodeStatus.None;

        #endregion Public Properties



        #region Public Methods

        public bool Approve(Guid nodeId, ApproveNodeStatus status)
        {
            if (Activity)
            {
                var result = ExecApprove(nodeId, status);
                if (status is not ApproveNodeStatus.Activity)
                {
                    Activity = false;
                }
                return result;
            }
            else
            {
                throw new BusinessException($"【{nodeId}】节点未激活，不能审批！");
            }
        }

        public virtual bool ExecApprove(Guid nodeId, ApproveNodeStatus status)
        {
            if (nodeId != Id)
            {
                return false;
            }
            Status = status;
            return true;
        }

        public virtual void Init()
        {
            Activity = true;
        }

        public virtual void SetParent(WorkNodeComplex nodeComplex)
        {
            Parent = nodeComplex;
            ParentId = nodeComplex.Id;
        }
        public virtual void SetFlow(WorkFlow flow)
        {
            Flow = flow;
            FlowId = flow.Id;
        }

        #endregion Public Methods
    }
}